package com.blueskykong.tm.core.concurrent.task;


import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

import ch.qos.logback.core.util.TimeUtil;

/**
 * @author keets
 */
public class BlockTask {

    private Lock lock;
    private Condition condition;
    private CountDownLatch countDownLatch;

    private AsyncCall asyncCall;

    /**
     * 是否被唤醒
     */
    private volatile static boolean Notify = false;

    /**
     * 是否被唤醒
     */
    private volatile static boolean remove = false;

    /**
     * 唯一标示key
     */
    private String key;

    /**
     * 数据状态用于业务处理
     */
    private int state = 0;


    public BlockTask() {
        /*
        lock = new ReentrantLock();
        condition = lock.newCondition();*/
    }

    public void countDownAwait() {
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            countDownLatch.countDown();
        }
    }

    public void countDown() {
        countDownLatch.countDown();
    }


    public void signal() {
        /*
        try {
            lock.lock();
            Notify = true;
            condition.signal();
        } finally {
            lock.unlock();
        }*/
        LockSupport.unpark(Thread.currentThread());
    }


    public void await() {
        /*
        try {
            lock.lock();
            condition.await();
        } catch (Exception e) {
        } finally {
            lock.unlock();
        }*/
        LockSupport.park();
    }

    public Object awaitUntil(int delayTime, TimeUnit timeUnit, AsyncCall errorAsyncCall)
        throws Throwable
    {
        long nanos;
        switch (timeUnit){
            case MILLISECONDS:
                nanos =timeUnit.toNanos(delayTime);
                break;
            case MICROSECONDS:
                nanos = timeUnit.toNanos(delayTime);
                break;
            default:
                nanos = timeUnit.convert(delayTime,TimeUnit.SECONDS);
        }
        LockSupport.parkNanos(nanos);
        return asyncCall != null ? asyncCall.callBack():errorAsyncCall.callBack();
    }


    public void setAsyncCall(AsyncCall asyncCall) {
        this.asyncCall = asyncCall;
    }

    public AsyncCall getAsyncCall() {
        return asyncCall;
    }

    public boolean isNotify() {
        return Notify;
    }

    public static void setNotify(boolean notify) {
        Notify = notify;
    }

    public static boolean isRemove() {
        return remove;
    }

    public static void setRemove(boolean remove) {
        BlockTask.remove = remove;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }


}
